﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using EdgeStatz.ESSystems.Objects;
using DigitalRune.Windows.TextEditor;

namespace EdgeStatz.DesignTools
{
    public partial class FormGenDesigner : UserControl
    {
        private List<FormDefinition> formDefs = new List<FormDefinition> { };

        public FormGenDesigner()
        {
            InitializeComponent();
            AutoGen autogen = new AutoGen();
            autogen.FormGeneratedEvent += new AutoGen.FormGenerated(autogen_FormGeneratedEvent);
            autogen.Dock = DockStyle.Fill;
            tabpage_CodeGenerator.Controls.Add(autogen);

            string modelpath = GlobalSystemSettings.ModelFilePath;
            if (modelpath == null || modelpath == "")
                throw new NullReferenceException("File path is empty or null.");

            autogen_FormGeneratedEvent();
        }

        void autogen_FormGeneratedEvent()
        {
            formDefs.Clear();
            formDefs.AddRange(Designer.FormEngine.FormDefinitions);
            string[] foldernames = Designer.FolderEngine.GetFolderNames();
            cbFileProp_Folder.Items.AddRange(foldernames);
            RefreshFileList();
        }
        public void Save() 
        {
            Designer.FormEngine.FormDefinitions = formDefs.ToArray();
            Designer.FormEngine.SaveModelFile();
        }

        #region File List Manager
        private void RefreshFileList()
        {
            lvFiles.Items.Clear();
            foreach (FormDefinition fdef in formDefs)
            {
                lvFiles.Items.Add(new ListViewItem(new string[]{fdef.Name, fdef.Folder, fdef.FilePath}));
            }
            ResetFileProperties();
            ResetParameterList();
            lvFiles.SelectedIndices.Clear();
            tabControlFiles.Enabled = true;
            tsbFile_Save.Enabled = false;
            tsbFile_Cancel.Enabled = false;
        }

        private void lvFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvFiles.SelectedIndices.Count != 1)
            {
                tabControlFiles.Enabled = false;
                return;
            }
            int index = lvFiles.SelectedIndices[0];
            if (formDefs.Count < index)
                throw new IndexOutOfRangeException("index value out of range");

            tbFileProp_Name.Text = formDefs[index].Name;
            tbFileProp_Path.Text = formDefs[index].FilePath;

            cbFileProp_Folder.SelectedItem = formDefs[index].Folder;

            tsbFile_Save.Enabled = true;
            tsbFile_Cancel.Enabled = true;

            LoadFileToTextEditor(formDefs[index].FilePath);
            RefreshParameterList();
            tabControlFiles.Enabled = true;
        }
        private void tsbFile_Save_Click(object sender, EventArgs e)
        {
            if (lvFiles.SelectedIndices.Count == 0)
            {
                // add new
                List<string> cp = new List<string>{};
                for(int i =0 ; i< lbCompileParams.Items.Count;i++)
                    cp.Add(lbCompileParams.Items[i].ToString());
                formDefs.Add(new FormDefinition(tbFileProp_Name.Text, 
                    cbFileProp_Folder.SelectedItem.ToString(),tbFileProp_Path.Text,cp.ToArray(), new string[]{}));
            }
            else
            {
                int index = lvFiles.SelectedIndices[0];
                List<string> cp = new List<string> { };
                for (int i = 0; i < lbCompileParams.Items.Count; i++)
                    cp.Add(lbCompileParams.Items[i].ToString());
                formDefs.RemoveAt(index);
                formDefs.Insert(index, new FormDefinition(tbFileProp_Name.Text,
                    cbFileProp_Folder.SelectedItem.ToString(), tbFileProp_Path.Text, cp.ToArray(), new string[]{}));
            }
            RefreshFileList();
            Save();
        }

        private void tsbFile_Cancel_Click(object sender, EventArgs e)
        {
            ResetFileProperties();
            ResetParameterList();
            lvFiles.SelectedIndices.Clear();
            tabControlFiles.Enabled = false;
            tsbFile_Save.Enabled = false;
            tsbFile_Cancel.Enabled = false;
        }

        private void tsbFile_Add_Click(object sender, EventArgs e)
        {
            ResetFileProperties();
            ResetParameterList();
            lvFiles.SelectedIndices.Clear();
            tabControlFiles.Enabled = true;
            tsbFile_Save.Enabled = false;
            tsbFile_Cancel.Enabled = false;
        }

        private void tsbFile_Delete_Click(object sender, EventArgs e)
        {
            if (lvFiles.SelectedIndices.Count != 1)
                return;

            if (MessageBox.Show("Are you sure you want to delete this file from the model?" +
                "\n(The source file will not be deleted)", "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                int index = lvFiles.SelectedIndices[0];
                if (formDefs.Count < index)
                    throw new IndexOutOfRangeException("index value out of range");
                formDefs.RemoveAt(index);
                RefreshFileList();
                tabControlFiles.Enabled = false;
                // Save to model.
            }
        } 
        #endregion

        #region File Properties
        private void ResetFileProperties()
        {
            tbFileProp_Name.Text = "";
            tbFileProp_Path.Text = "";
            cbFileProp_Folder.SelectedIndex = -1;
        }
        private void FileProperties_Changed(object sender, EventArgs e)
        {
            tsbFile_Save.Enabled = true;
            tsbFile_Cancel.Enabled = true;
        }

        private void bFileProp_Browse_Click(object sender, EventArgs e)
        {
            OpenFileDialog filedialog = new OpenFileDialog();
            filedialog.Title = "Select Source File";
            filedialog.Filter = "C# Source Code|*.cs|VB Source Code|*.vb|All Files|*.*";
            filedialog.Multiselect = false;
            if (!tbFileProp_Path.Text.Trim().Equals(""))
                filedialog.FileName = tbFileProp_Path.Text;
            if (filedialog.ShowDialog() == DialogResult.OK)
                tbFileProp_Path.Text = filedialog.FileName;
        }
        #endregion

        #region File Parameters
        private void ResetParameterList()
        {
            lbCompileParams.Items.Clear();
        }
        private void RefreshParameterList()
        {
            int index = lvFiles.SelectedIndices[0];
            lbCompileParams.Items.Clear();
            foreach (string cp in formDefs[index].CompileParameters)
                lbCompileParams.Items.Add(cp);
        }
        private void tsbParam_Add_Click(object sender, EventArgs e)
        {
            CompileParams paramprops = new CompileParams();
            if (paramprops.ShowDialog() == DialogResult.OK)
            {
                lbCompileParams.Items.Add(paramprops.Parameter);
            }
        }

        private void tsbParam_Delete_Click(object sender, EventArgs e)
        {
            if (lbCompileParams.SelectedIndex == -1)
                return;
            if (MessageBox.Show("You are about to delete this parameter.\nAre you sure?",
                "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                lbCompileParams.Items.Remove(lbCompileParams.SelectedItem);
        }
        
        private void tsbParam_Edit_Click(object sender, EventArgs e)
        {
            if (lbCompileParams.SelectedIndex == -1)
                return;
            CompileParams paramprops = new CompileParams(lbCompileParams.SelectedItem.ToString());
            if (paramprops.ShowDialog() == DialogResult.OK)
            {
                int index = lbCompileParams.SelectedIndex;
                lbCompileParams.Items.RemoveAt(index);
                lbCompileParams.Items.Insert(index, paramprops.Parameter);
            }
        }
        #endregion

        #region Text Editor

        private void LoadFileToTextEditor(string path)
        {
            textEditor.LoadFile(path);
        }        

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }

            textEditor.Document.TextContent = "";
            textEditor.Refresh();
        }
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }

            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "Open File Dialog";
            openFileDialog.Filter = "C# Source File|*.cs|VB Source File|*.vb|Text File|*.txt|All Files|*.*";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
                textEditor.LoadFile(openFileDialog.FileName);
        }
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }

            if (String.IsNullOrEmpty(textEditor.FileName))
                saveAsToolStripMenuItem_Click(sender, e);
            else
                textEditor.SaveFile(textEditor.FileName);
        }
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = "Save File Dialog";
            saveFileDialog.Filter = "C# Source File|*.cs|VB Source File|*.vb|Text File|*.txt|All Files|*.*";
            saveFileDialog.AddExtension = true;

            if (!String.IsNullOrEmpty(textEditor.FileName))
                saveFileDialog.FileName = textEditor.FileName;

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
                textEditor.SaveFile(saveFileDialog.FileName);
        }
        private void useFileAsSourceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabControl_Main.SelectedTab = tabpage_FilesList;
            tbFileProp_Path.Text = textEditor.FileName;
        }
        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }
            new DigitalRune.Windows.TextEditor.Actions.Undo().Execute(textEditor);
        }
        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }
            new DigitalRune.Windows.TextEditor.Actions.Redo().Execute(textEditor);
        }
        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }
            new DigitalRune.Windows.TextEditor.Actions.Cut().Execute(textEditor);
        }
        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }
            new DigitalRune.Windows.TextEditor.Actions.Copy().Execute(textEditor);
        }
        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }
            new DigitalRune.Windows.TextEditor.Actions.Paste().Execute(textEditor);
        }
        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabControl_Main.SelectedTab != tabpage_TextEditor) { return; }
            new DigitalRune.Windows.TextEditor.Actions.SelectWholeDocument().Execute(textEditor);
        }
        private void rulerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            rulerToolStripMenuItem.Checked = !rulerToolStripMenuItem.Checked;
            textEditor.ShowVRuler = rulerToolStripMenuItem.Checked;
            textEditor.ShowHRuler = rulerToolStripMenuItem.Checked;
        }
        private void lineNumbersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lineNumbersToolStripMenuItem.Checked = !lineNumbersToolStripMenuItem.Checked;
            textEditor.ShowLineNumbers = lineNumbersToolStripMenuItem.Checked;
        }
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void aboutTextToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
        private void CompletionRequest(object sender, 
            DigitalRune.Windows.TextEditor.Completion.CompletionEventArgs e)
        {
            if (textEditor.CompletionWindowVisible)
                return;
            // e.Key == '\0' means that the user triggered the CompletionRequest by pressing <Ctrl> + <Space>.
            if (e.Key == '\0')
            {
                textEditor.ShowCompletionWindow(new CodeCompletionDataProvider(), e.Key, false);
            }
            else if (char.IsLetter(e.Key))
            {
                textEditor.ShowCompletionWindow(new CodeCompletionDataProvider(), e.Key, true);
            }
        }
        #endregion
    }
}
